package net.nohaven.proj.javeau.fs.hybrid;

import java.io.File;

import net.nohaven.proj.javeau.fs.crypt.CFSFactory;
import net.nohaven.proj.javeau.fs.crypt.CFSFilesystem;
import net.nohaven.proj.javeau.fs.crypt.CFSUtils;
import net.nohaven.proj.javeau.fs.exceptions.ConditionsNotMetException;
import net.nohaven.proj.javeau.fs.exceptions.EntityAlreadyPresentException;
import net.nohaven.proj.javeau.fs.exceptions.EntityNotFoundException;
import net.nohaven.proj.javeau.fs.exceptions.GenericIOException;
import net.nohaven.proj.javeau.fs.exceptions.WrongPassException;
import net.nohaven.proj.javeau.fs.model.FSDirectory;
import net.nohaven.proj.javeau.fs.model.FSFileWriter;
import net.nohaven.proj.javeau.fs.model.FSItem;
import net.nohaven.proj.javeau.fs.model.Filesystem;
import net.nohaven.proj.javeau.fs.real.RFSFilesystem;
import net.nohaven.proj.javeau.ui.FSPanelCompanion;
import net.nohaven.proj.javeau.utils.Utils;

public class HFilesystem implements Filesystem {
	private Filesystem base = new RFSFilesystem();
	private Filesystem current = base;

	private FSPanelCompanion parent;

	public HFilesystem(FSPanelCompanion parent) {
		this.parent = parent;
	}

	public void cd(String name, char[] pwd) throws EntityNotFoundException {
		current.cd(name);

		//is it a secure directory?
		if (!CFSUtils.isSecretDirectory(current.getPwd()))
			return;

		//yes it is
		if (pwd == null)
			pwd = parent.askPassword();

		if (Utils.isEmpty(pwd))
			cdUp();
		else
			try {
				current = new CFSFactory(new File(base.getPwd().getPath()), pwd)
						.getInstance(true);
			} catch (ConditionsNotMetException e) {
				parent.reportError(e.getMessage());
				cdUp();
			} catch (GenericIOException e) {
				e.printStackTrace();
				cdUp();
			} catch (WrongPassException e) {
				parent.reportError("Wrong password");
				cdUp();
			}
	}

	public void cd(String name) throws EntityNotFoundException {
		cd(name, null);
	}

	public void cdNoSwap(String name) throws EntityNotFoundException {
		current.cd(name);
	}

	public void cdUp() {
		if (current instanceof CFSFilesystem)
			if (current.getPwd().getPath().equals("/")) {
				current.close();
				current = base;
			}

		current.cdUp();
	}

	public void close() {
		current.close();
	}

	public FSFileWriter createFile(String name)
			throws EntityAlreadyPresentException, GenericIOException {
		return current.createFile(name);
	}

	public void delete(String name) throws ConditionsNotMetException {
		current.delete(name);
	}

	public FSItem get(String name) {
		return current.get(name);
	}

	public FSDirectory getPwd() {
		return current.getPwd();
	}

	public void goToRoot() {
		current.goToRoot();
	}

	public FSItem[] ls() {
		return current.ls();
	}

	public void mkDir(String name) throws EntityAlreadyPresentException {
		current.mkDir(name);
	}

	public void rename(String name, String newName)
			throws EntityNotFoundException, EntityAlreadyPresentException {
		current.rename(name, newName);
	}

	public boolean isSecure() {
		return current instanceof CFSFilesystem;
	}
}
